class Router{
    constructor(){
        this.stack = []
    }
    compose(ctx,stack,next){
        function dispatch(i){
            if(i === stack.length) return next()
            let {middleware} = stack[i]
            return Promise.resolve(middleware(ctx, () => dispatch(i+1)));
        }
        return dispatch(0)
    }
    routes(){
        return async (ctx,next)=>{
           const stack = this.stack.filter((layer) => layer.match(ctx));
           return this.compose(ctx,stack, next);
        }
    }
}
class Layer {
  constructor(path, middleware,method) {
    this.path = path;
    this.middleware = middleware;
    this.method = method
  }
  match(ctx){
    return ctx.path == this.path && ctx.method.toLowerCase() === this.method
  }
}
['get','post','put','delete'].forEach(method=>{
    Router.prototype[method] = function(path,middleware){
        this.stack.push(new Layer(path, middleware, method));
    }
})
export default Router